package ast.exp;

import icg.EQTemp;
import icg.Quadruple;
import ts.SymbolTable;
import ast.Node;
import ast.type.OpType;
import ast.type.Type;

public class UnaExp extends Expression {
	private Expression exp;
	private OpType opType;

	public UnaExp(OpType opType, Expression exp) {
		this.exp = exp;
		this.opType = opType;
	}

	@Override
	public String toString() {
		return "<UnaExp type=\"" + opType + "\">\n" + exp + "</UnaExp>";
	}

	@Override
	public Type typeCheck() {
		type = exp.typeCheck();
		if (type != Type.ERROR) {
			if (type == Type.BOOLEAN && opType == OpType.NOT)
				return type;
			if (type == Type.INTEGER && opType == OpType.PLUS)
				return type;
			if (type == Type.INTEGER && opType == OpType.MINUS)
				return type;
		}
		System.out.println("invalid type operator in unary expression");
		SymbolTable.errors++;
		return Type.ERROR;
	}

	@Override
	public void genCode() {
		if (opType == OpType.MINUS) {
			exp.genCode();
			this.addr = new EQTemp();
			Node.icg.gen(Quadruple.negative(this.addr, exp.addr));
		} else { //OpType.NOT
			exp.trueL = this.falseL;
			exp.falseL = this.trueL;
			exp.genCode();
			//this.addr = exp.addr;
			/*if (this.falseL.equals(EQLabel.FALL)) {
				EQLabel.useLabel(exp.falseL);
			}*/
		}
	}
}
